package com.sinoatma.physignsmonitor.ble

import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.bluetooth.*
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.lifecycle.Observer
import com.jeremyliao.liveeventbus.LiveEventBus
import com.sinoatma.physignsmonitor.MyApp
import com.sinoatma.physignsmonitor.R
import com.sinoatma.physignsmonitor.bean.MsgBleData
import com.sinoatma.physignsmonitor.bean.SendCmd
import com.sinoatma.physignsmonitor.constant.Constant.bpNotify
import com.sinoatma.physignsmonitor.constant.Constant.bpWrite
import com.sinoatma.physignsmonitor.constant.Constant.spoNotify
import com.sinoatma.physignsmonitor.constant.Constant.spoWrite
import com.sinoatma.physignsmonitor.constant.Constant.tempAntiKickCmd
import com.sinoatma.physignsmonitor.constant.Constant.temperatureNotify
import com.sinoatma.physignsmonitor.constant.Constant.temperatureWrite
import com.sinoatma.physignsmonitor.utils.Utils
import com.sinoatma.physignsmonitor.utils.Utils.hexToBytes
import kotlinx.coroutines.*
import java.util.*

@SuppressLint("MissingPermission")
class BleBloodTransService : Service() {

    // 用于存储两个蓝牙设备对应的Gatt对象，分别管理与两个设备的连接和通信
    private lateinit var bluetoothGatt1: BluetoothGatt
    private lateinit var bluetoothGatt2: BluetoothGatt
    private lateinit var bluetoothGatt3: BluetoothGatt
    // 存储两个设备对应的写入特性，用于向不同设备写入数据
    private lateinit var writingCharacteristic1: BluetoothGattCharacteristic
    private lateinit var writingCharacteristic2: BluetoothGattCharacteristic
    private lateinit var writingCharacteristic3: BluetoothGattCharacteristic
    var characteristicStatus=0

    // 获取蓝牙管理器和蓝牙适配器实例
    val bluetoothManager by lazy { getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager }
    val bluetoothAdapter by lazy { bluetoothManager.adapter }



    // 第一个设备的Gatt回调，处理连接状态变化、服务发现、特性变化等相关逻辑
    val gattCallback1 = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
            super.onConnectionStateChange(gatt, status, newState)
            Log.e("zsy", "Connection State Changed for Device 1: " + newState + "," + BluetoothProfile.STATE_DISCONNECTED)
            when (newState) {
                BluetoothProfile.STATE_DISCONNECTED -> { // 设备1连接断开
                    bluetoothGatt1.close()
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(4, bleData = "血氧设备已断开，如需测量请佩戴设备！"))
                }
                BluetoothProfile.STATE_CONNECTED -> { // 设备1连接成功
                    Log.e("zsy", "设备1连接成功")
                    gatt!!.discoverServices()
                }
                else -> {
                    Log.e("zsy", "设备1其他状态")
                }
            }
        }

        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            super.onServicesDiscovered(gatt, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                val services: List<BluetoothGattService>? = bluetoothGatt1?.services
                services?.forEach { service ->
                    val characteristics: List<BluetoothGattCharacteristic> = service.characteristics
                    characteristics.forEach { characteristic ->
                        // 判断是否是设备1需要监听的特性（通知特性）
                        if (characteristic.uuid == spoNotify) {
                            val isEnableNotification = bluetoothGatt1!!.setCharacteristicNotification(characteristic, true)
                            if (isEnableNotification) {
                                val descriptorList = characteristic.descriptors
                                if (descriptorList != null && descriptorList.size > 0) {
                                    for (descriptor in descriptorList) {
                                        if (descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) && bluetoothGatt1.writeDescriptor(descriptor)) {
                                            Log.e("zsyNotify111", "设备1 enable notify success..........")
                                            LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type = 3))
                                        }
                                    }
                                }
                            } else {
                                bluetoothGatt1.close()
                                characteristicStatus=0
                                Log.e("zsyNotify", "血氧设备1 enable notify fail..........")
                            }
                        }
                        // 判断是否是设备1需要写入数据的特性
                        if (characteristic.uuid == spoWrite) {
                            Log.e("zsyNotify", "血氧设备1 ${characteristic.uuid.toString() } 写入指令特性..........")
                            writingCharacteristic1=characteristic
                        }
                    }
                }
            }
        }

        override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
            super.onCharacteristicChanged(gatt, characteristic)
            var notifyCode = ""
            var bytes: ByteArray?
            if (characteristic.uuid == spoNotify) {
                bytes = characteristic.value
                notifyCode = Utils.bytesToHexFun(bytes)
                if (notifyCode.isNotEmpty() && notifyCode.length > 30) {
                    if (notifyCode.startsWith("5500FF",true)) {
                        var temp = notifyCode.subSequence(14, 22)
                        LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type = 2, bleData ="$temp"))
                        notifyCode=""
                    }
                }
            }
        }

        override fun onDescriptorWrite(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int) {
            super.onDescriptorWrite(gatt, descriptor, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 描述符写入操作成功的情况
//                Log.d("zsy", "描述符写入成功，descriptor: ${descriptor?.uuid}")
                // 在这里可以添加后续成功后的业务逻辑，比如继续进行其他蓝牙操作，通知相关界面更新等
            } else {
                // 描述符写入操作失败的情况
//                Log.e("zsy", "描述符写入失败，错误码: $status，descriptor: ${descriptor?.uuid}")
                // 根据具体的业务需求，可能需要采取一些补救措施，例如重新尝试写入、提示用户操作失败等
            }
        }
    }

    // 第二个设备的Gatt回调，处理连接状态变化、服务发现、特性变化等相关逻辑，与第一个设备类似但对应不同的UUID等
    val gattCallback2 = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
            super.onConnectionStateChange(gatt, status, newState)
            Log.e("zsy", "Connection State Changed for Device 2: " + newState + "," + BluetoothProfile.STATE_DISCONNECTED)
            when (newState) {
                BluetoothProfile.STATE_DISCONNECTED -> { // 设备2连接断开
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(6, bleData = "血压计已关闭，如需测量请开启设备！"))
                    bluetoothGatt2.close()
                }
                BluetoothProfile.STATE_CONNECTED -> { // 设备2连接成功
                    Log.e("zsy", "设备2连接成功")
                    gatt!!.discoverServices()
                }
                else -> {
                    Log.e("zsy", "设备2其他状态")
                }
            }
        }

        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            super.onServicesDiscovered(gatt, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                val services: List<BluetoothGattService>? = bluetoothGatt2?.services
                services?.forEach { service ->
                    val characteristics: List<BluetoothGattCharacteristic> = service.characteristics
                    characteristics.forEach { characteristic ->
                        // 判断是否是设备2需要监听的特性（通知特性）
                        if (characteristic.uuid == bpNotify) {
                            val isEnableNotification =
                                bluetoothGatt2!!.setCharacteristicNotification(characteristic, true)
                            if (isEnableNotification) {
                                val descriptorList = characteristic.descriptors
                                if (descriptorList != null && descriptorList.size > 0) {
                                    for (descriptor in descriptorList) {
                                        if (descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) && bluetoothGatt2.writeDescriptor(descriptor)) {
                                            Log.e("zsyNotify111", "血压设备1 enable notify success..........")
                                            LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type = 5))
                                        }
                                    }
                                }
                            } else {
                                bluetoothGatt2.close()
                                Log.e("zsyNotify", "血压设备1 enable notify fail..........")
                            }
                        }

                        // 判断是否是设备2需要写入数据的特性
                        if (characteristic.uuid == bpWrite) {
                            writingCharacteristic2 = characteristic
                        }
                    }
                }
            }
        }

        override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
            super.onCharacteristicChanged(gatt, characteristic)
            var notifyCode = ""
            var bytes: ByteArray?
            if (characteristic.uuid == bpNotify) {
                bytes = characteristic.value
                notifyCode = Utils.bytesToHexFun(bytes)
                Log.e("zsy","血压计${notifyCode}")
                if (notifyCode.isNotEmpty() ) {
                 LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type =1, bleData ="$notifyCode"))
                 notifyCode=""
                }
            }
        }

        override fun onDescriptorWrite(
            gatt: BluetoothGatt?,
            descriptor: BluetoothGattDescriptor?,
            status: Int
        ) {
            super.onDescriptorWrite(gatt, descriptor, status)
        }
    }

    // 第三个设备的Gatt回调，处理连接状态变化、服务发现、特性变化等相关逻辑，与第一个设备类似但对应不同的UUID等
    val gattCallback3 = object : BluetoothGattCallback() {
        override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
            super.onConnectionStateChange(gatt, status, newState)
            Log.e("zsy", "Connection State Changed for Device 2: " + newState + "," + BluetoothProfile.STATE_DISCONNECTED)
            when (newState) {
                BluetoothProfile.STATE_DISCONNECTED -> { // 设备2连接断开
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(9, bleData = "温度计已关闭，如需测量请开启设备！"))
                    bluetoothGatt3.close()
                }
                BluetoothProfile.STATE_CONNECTED -> { // 设备2连接成功
                    Log.e("zsy", "设备3连接成功")
                    gatt!!.discoverServices()
                }
                else -> {
                    Log.e("zsy", "设备3其他状态")
                }
            }
        }

        override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
            super.onServicesDiscovered(gatt, status)
            if (status == BluetoothGatt.GATT_SUCCESS) {
                val services: List<BluetoothGattService>? = bluetoothGatt3?.services
                services?.forEach { service ->
                    val characteristics: List<BluetoothGattCharacteristic> = service.characteristics
                    characteristics.forEach { characteristic ->
                        // 判断是否是设备2需要监听的特性（通知特性）
                        if (characteristic.uuid == temperatureNotify) {
                            val isEnableNotification =
                                bluetoothGatt3!!.setCharacteristicNotification(characteristic, true)
                            if (isEnableNotification) {
                                val descriptorList = characteristic.descriptors
                                if (descriptorList != null && descriptorList.size > 0) {
                                    for (descriptor in descriptorList) {
                                        if (descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) && bluetoothGatt3.writeDescriptor(descriptor)) {
                                            Log.e("zsyNotify111", "血压设备1 enable notify success..........")
                                            LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type = 8))
                                        }
                                    }
                                }
                            } else {
                                bluetoothGatt3.close()
                                Log.e("zsyNotify", "血压设备1 enable notify fail..........")
                            }
                        }

                        // 判断是否是设备2需要写入数据的特性
                        if (characteristic.uuid == temperatureWrite) {

                            writingCharacteristic3 = characteristic
                            writeData3("${tempAntiKickCmd}")
                        }
                    }
                }
            }
        }

        override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
            super.onCharacteristicChanged(gatt, characteristic)
            var notifyCode = ""
            var bytes: ByteArray?
            if (characteristic.uuid == temperatureNotify) {
                bytes = characteristic.value
                notifyCode = Utils.bytesToHexFun(bytes)
                Log.e("zsy","温度计${notifyCode}")
                if (notifyCode.isNotEmpty() && notifyCode.length>30 && notifyCode.startsWith("55000A010C00",true) ) {
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(type =7, bleData ="${notifyCode.substring(28,notifyCode.length-2)}"))
                    notifyCode=""
                }
            }
        }

        override fun onDescriptorWrite(gatt: BluetoothGatt?, descriptor: BluetoothGattDescriptor?, status: Int) {
            super.onDescriptorWrite(gatt, descriptor, status)
        }
    }






    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        if (intent == null) {
            Log.e("BleStartService", "onStartCommand received a null intent")
            return START_STICKY
        }
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onUnbind(intent: Intent?): Boolean {
        return super.onUnbind(intent)
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "${getString(R.string.app_name)} Service"
            val descriptionText = "Channel for foreground service"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            val notificationManager: NotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    companion object {
        private const val CHANNEL_ID = "com.sinoatma.physignsmonitor.FOREGROUND_SERVICE_CHANNEL"
        private const val NOTIFICATION_ID = 203
    }

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("智慧输血监护")
            .setContentText("Service is running...")
            .setSmallIcon(R.mipmap.ic_launcher) // Replace with your app's drawable
            .build()
        startForeground(NOTIFICATION_ID, notification)
        LiveEventBus.get("receiveCmd1", SendCmd::class.java).observeForever(observerCmd1)
        LiveEventBus.get("receiveCmd2", SendCmd::class.java).observeForever(observerCmd2)
        LiveEventBus.get("receiveCmd3", SendCmd::class.java).observeForever(observerCmd3)
    }

    // 用于处理第一个设备相关命令的观察者
    val observerCmd1 = Observer<SendCmd> { it ->
        when (it.type) {
            1 -> {
                writeData1(it.cmd)
            }
            2 -> {
                disConnect1()
            }
            3 -> {
                if (it.cmd.isNotEmpty()) {
                    val device = bluetoothAdapter.getRemoteDevice(it.cmd)
                    if (device != null) {
                        Log.e("zsy", "血氧=${it}==${device.name}")
                        bluetoothGatt1 = device.connectGatt(
                            MyApp.context,
                            true,
                            gattCallback1,
                            BluetoothDevice.TRANSPORT_LE
                        )
                    }
                }else{
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(4, bleData = "请先配置外设！"))
                }
            }
        }
    }

    // 用于处理第二个设备相关命令的观察者
    val observerCmd2 = Observer<SendCmd> { it ->
        when (it.type) {
            1 -> {
                writeData2(it.cmd)
            }
            2 -> {
                disConnect2()
            }
            3 -> {
                if (it.cmd.isNotEmpty()) {
                    val device = bluetoothAdapter.getRemoteDevice(it.cmd)
                    if (device != null) {
                        Log.e("zsy", "血压=${it}==${device.name}")
                        bluetoothGatt2 = device.connectGatt(
                            MyApp.context,
                            true,
                            gattCallback2,
                            BluetoothDevice.TRANSPORT_LE
                        )
                    }
                }else{
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(4, bleData = "请先配置外设！"))
                }
            }
        }
    }

    // 用于处理第二个设备相关命令的观察者
    val observerCmd3 = Observer<SendCmd> { it ->
        when (it.type) {
            1 -> {
                writeData3(it.cmd)
            }
            2 -> {
                disConnect3()
            }
            3 -> {
                if (it.cmd.isNotEmpty()) {
                    val device = bluetoothAdapter.getRemoteDevice(it.cmd)
                    if (device != null) {
                        Log.e("zsy", "温度计=${it}==${device.name}")
                        bluetoothGatt3 = device.connectGatt(MyApp.context, true, gattCallback3, BluetoothDevice.TRANSPORT_LE)
                    }
                }else{
                    LiveEventBus.get("DataNotify", MsgBleData::class.java).post(MsgBleData(9, bleData = "请先配置外设！"))
                }
            }
        }
    }



    // 主动断开第一个设备连接的函数
    fun disConnect1() {
        if (::bluetoothGatt1.isInitialized && bluetoothGatt1 != null) {
            Log.e("zsy", "主动断开设备连接")
            bluetoothGatt1.disconnect()
            bluetoothGatt1.close()
        }
    }

    // 主动断开第二个设备连接的函数
    fun disConnect2() {
        if (::bluetoothGatt2.isInitialized && bluetoothGatt2 != null) {
            Log.e("zsy", "主动断开设备连接")
            bluetoothGatt2.disconnect()
            bluetoothGatt2.close()
        }
    }
    // 主动断开第二个设备连接的函数
    fun disConnect3() {
        if (::bluetoothGatt3.isInitialized && bluetoothGatt3 != null) {
            Log.e("zsy", "主动断开设备连接")
            bluetoothGatt3.disconnect()
            bluetoothGatt3.close()
        }
    }

    // 向第一个设备写入数据的函数
    fun writeData1(data: String) {
        if (::writingCharacteristic1.isInitialized) {
            if (writingCharacteristic1 != null) {
                writingCharacteristic1.value =hexToBytes(data)
                if (bluetoothGatt1 != null) {
//                    Log.e("zsy", "向设备1写入指令${writingCharacteristic1.uuid.toString()}==${data}")
                    bluetoothGatt1.writeCharacteristic(writingCharacteristic1)
                }
            }
        }
    }

    // 向第二个设备写入数据的函数
    fun writeData2(data: String) {
        if (::writingCharacteristic2.isInitialized) {
            if (writingCharacteristic2 != null) {
                writingCharacteristic2.value = hexToBytes(data)
                if (bluetoothGatt2 != null) {
                    bluetoothGatt2.writeCharacteristic(writingCharacteristic2)
                }
            }
        }
    }

    // 向第二个设备写入数据的函数
    fun writeData3(data: String) {
        if (::writingCharacteristic3.isInitialized) {
            if (writingCharacteristic3 != null) {
                writingCharacteristic3.value = hexToBytes(data)
                if (bluetoothGatt3 != null) {
                    Log.e("zsy","写入指令=${data}")
                    bluetoothGatt3.writeCharacteristic(writingCharacteristic3)
                }
            }
        }
    }

    fun hexToBytes(hexStr: String): ByteArray? {
        var hexStr = hexStr
        val len = hexStr.length
        hexStr = hexStr.uppercase(Locale.getDefault())
        val des: ByteArray
        return if (len % 2 != 0 || len == 0) {
            null
        } else {
            val halfLen = len / 2
            des = ByteArray(halfLen)
            val tempChars = hexStr.toCharArray()
            for (i in 0 until halfLen) {
                val c1 = tempChars[i * 2]
                val c2 = tempChars[i * 2 + 1]
                var tempI = 0
                tempI += if (c1 >= '0' && c1 <= '9') {
                    c1.code - '0'.code shl 4
                } else if (c1 >= 'A' && c1 <= 'F') {
                    c1.code - 'A'.code + 10 shl 4
                } else {
                    return null
                }
                tempI += if (c2 >= '0' && c2 <= '9') {
                    c2.code - '0'.code
                } else if (c2 >= 'A' && c2 <= 'F') {
                    c2.code - 'A'.code + 10
                } else {
                    return null
                }
                des[i] = tempI.toByte()
                // System.out.println(des[i]);
            }
            des
        }
    }
}